#[allow(dead_code)]


fn match_example() {
    let number = 13;

    match number {
        1=> {
            println!("One");
        }
        2|3|4|6|8 =>{
            println!("2|3|4|6|8");
        }
        13..=19 => {
            println!("13...19");
        }
        _=> {
            println!("Ain't special")
        }
    }

    let boolean = true;
    let binary = match boolean {
        false=>0,
        true=>1,
    };

    println!("{} -> {}",boolean,binary);
}

//元组解构
fn tuple_desprate() {
    let triple = (0,-2,-3);
    match triple {
        (0,y,z) => {
            println!("First is zero, 'y' is {:?},and 'z'is {:?}",y,z);
        }
        (1,..)=>println!("First is '1' and the rest doesn't matter"),
        _ => println!("it doesn't matter any value"),
    }
}

//枚举
fn enum_desprate() {
    enum Color {
        Red,
        Green,
        Blue,
        RGB(u32,u32,u32),
        HSV(u32,u32,u32),
        HSL(u32, u32, u32),
        CMY(u32, u32, u32),
        CMYK(u32, u32, u32, u32),
    }

    let color = Color::RGB(122,17,40);
    println!("What color is it?");
    match color {
        Color::Red   => println!("The color is Red!"),
        Color::Blue  => println!("The color is Blue!"),
        Color::Green => println!("The color is Green!"),
        Color::RGB(r, g, b) =>
            println!("Red: {}, green: {}, and blue: {}!", r, g, b),
        Color::HSV(h, s, v) =>
            println!("Hue: {}, saturation: {}, value: {}!", h, s, v),
        Color::HSL(h, s, l) =>
            println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l),
        Color::CMY(c, m, y) =>
            println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y),
        Color::CMYK(c, m, y, k) =>
            println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!",
                     c, m, y, k),
        // 不需要其它分支，因为所有的情形都已覆盖
    }
}

pub fn struct_desprate() {
    struct Foo {x: (u32,u32),y: u32}

    let foo = Foo {x:(1,2),y:3};
    let Foo {x:(xpos,ypos),y:z} = foo;
    println!("Pos({},{},{})",xpos,ypos,z);


    //解构并重命名
    let Foo {y: i,x: j} = foo;
    println!("i = {:?}, j = {:?}",i,j);

    //也可以忽略某些变量
    let Foo {y,..} = foo;
    println!("y = {}",y);

}

fn point_refer_desprate() {
    let reference = &4;
    match reference {
        /*
         如果用 `&val` 这个模式去匹配 `reference`，就相当于做这样的比较：
        `&i32`（译注：即 `reference` 的类型）
        `&val`（译注：即用于匹配的模式）
        ^ 我们看到，如果去掉匹配的 `&`，`i32` 应当赋给 `val`。
        译注：因此可用 `val` 表示被 `reference` 引用的值 4。
        */
        &val => println!("Got a value via destructuring: {:?}",val),
    }
    match *reference{
        val=>println!("Got a value via dereferencing: {:?}",val),
    }

    // 如果一开始就不用引用，会怎样？ `reference` 是一个 `&` 类型，因为赋值语句
    // 的右边已经是一个引用。但下面这个不是引用，因为右边不是。
    let _not_a_reference = 3;

    // Rust 对这种情况提供了 `ref`。它更改了赋值行为，从而可以对具体值创建引用。
    // 下面这行将得到一个引用。
    let ref _is_a_reference = 3;

    // 相应地，定义两个非引用的变量，通过 `ref` 和 `ref mut` 仍可取得其引用。
    let value = 5;
    let mut mut_value = 6;

    // 使用 `ref` 关键字来创建引用。
    // 译注：下面的 r 是 `&i32` 类型，它像 `i32` 一样可以直接打印，因此用法上
    // 似乎看不出什么区别。但读者可以把 `println!` 中的 `r` 改成 `*r`，仍然能
    // 正常运行。前面例子中的 `println!` 里就不能是 `*val`，因为不能对整数解
    // 引用。
    match value {
        ref r => println!("Got a reference to a value: {:?}", r),
    }

    // 类似地使用 `ref mut`。
    match mut_value {
        ref mut m => {
            // 已经获得了 `mut_value` 的引用，先要解引用，才能改变它的值。
            *m += 10;
            println!("We added 10. `mut_value`: {:?}", m);
        },
    }
}

//卫语句可以用来过滤分支
fn guard_example() {
    let pair = (2,-2);
    println!("Tell me about {:?}",pair);
    match pair {
        (x,y) if x ==y =>println!("These are twins"),
        (x,y) if x + y == 0=>println!("Antimatter,kaboom!"),
        (x,_) if x % 2 == 1 => println!("The first one is odd"),
        _=>println!("No correlation..."),
    }
}

//函数绑定

fn age()->u32 {
    15
}

fn some_number() -> Option<u32> {
    Some(42)
}

fn func_example() {
    println!("Tell me what type of person you are");

    match age() {
        0             => println!("I haven't celebrated my first birthday yet"),
        // 可以直接匹配（`match`） 1 ..= 12，但那样的话孩子会是几岁？
        // 相反，在 1 ..= 12 分支中绑定匹配值到 `n` 。现在年龄就可以读取了。
        n @ 1  ..= 12 => println!("I'm a child of age {:?}", n),
        n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n),
        // 不符合上面的范围。返回结果。
        n             => println!("I'm an old person of age {:?}", n),
    }

    match some_number() {
        Some(n@42) =>println!("The Answer: {}!",n),
        Some(n)=>println!("Not interesting {}",n),
        _=>(),
    }
}